import java.io.*;
import java.net.URL;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class DownFileUtil extends  Thread{

    private  String rootPath = "F:\\m3u8dir";
    private  int threadCount = 10;
    private  String videoPath = "https://baidu.com-v-baidu.com/20180811/5487_57c6ec5e/1000k/hls/index.m3u8";
    boolean composeFlag = false;//文件合成结果
    int during = 0;//下载进度

    public DownFileUtil(String rootPath,String videoPath,int threadCount){
        this.rootPath=rootPath.trim();
        this.videoPath=videoPath.trim();
        this.threadCount=threadCount;
    }
    
    public  void run (){
        long startTime = Calendar.getInstance().getTimeInMillis();
        String indexPath = videoPath;
        String prePath = indexPath.substring(0,indexPath.lastIndexOf("/")+1);
        //下载索引文件
        String indexStr = getIndexFile(indexPath);
        //解析索引文件
        List videoUrlList = analysisIndex(indexStr);

        //生成文件下载目录
        String uuid = UUID.randomUUID().toString().replaceAll("-","");
        String fileRootPath = rootPath+File.separator+uuid;
        File fileDir = new File(fileRootPath);
        if(!fileDir.exists()){
            fileDir.mkdirs();
        }
        //下载视频片段，分成50个线程切片下载
        HashMap keyFileMap = new HashMap();
        int downForThreadCount = videoUrlList.size()/threadCount;
        for(int i=0;i<videoUrlList.size();i+=downForThreadCount){
            int end = i+downForThreadCount-1;
            if(end>videoUrlList.size()){
                end = videoUrlList.size()-1;
            }
            new DownLoadNode(videoUrlList,i,end,keyFileMap,prePath,fileRootPath).start();
        }
        //等待下载
        while (keyFileMap.size()<videoUrlList.size()){
            during = (keyFileMap.size()*100)/videoUrlList.size();
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        //合成视频片段
        composeFile(fileRootPath+File.separator+uuid+".mp4",keyFileMap);
        composeFlag = true;
        long durTime = Calendar.getInstance().getTimeInMillis()-startTime;
        System.out.println("下载完成"+indexPath+",耗时"+durTime);
    }


    /**
     * 视频片段合成
     * @param fileOutPath
     * @param keyFileMap
     */
    public  void composeFile(String fileOutPath,HashMap<Integer,String> keyFileMap){
        boolean delFlag = false;
        try {
            FileOutputStream fileOutputStream = new FileOutputStream(new File(fileOutPath));
            byte[] bytes = new byte[1024];
            int length = 0;
            for(int i=0;i<keyFileMap.size();i++){
                String nodePath = keyFileMap.get(i);
                File file = new File(nodePath);
                if(!file.exists())
                    continue;
                FileInputStream fis = new FileInputStream(file);
                while ((length = fis.read(bytes)) != -1) {
                    fileOutputStream.write(bytes, 0, length);
                }
                fis.close();
            }
            fileOutputStream.close();
            delFlag = true;
        }catch (Exception e){
            e.printStackTrace();
            delFlag = false;
        }
        if(delFlag){//合成完成，删除碎片文件
            for(int i=0;i<keyFileMap.size();i++){
                String nodePath = keyFileMap.get(i);
                File file = new File(nodePath);
                file.delete();
            }
        }
    }




    public  List analysisIndex(String content){
        List<String> list = new ArrayList<String>();
        if(content.contains("http")){
            Pattern pattern = Pattern.compile("http://.*");
            Matcher ma = pattern.matcher(content);
            while(ma.find()){
                String s = ma.group();
                list.add(s);
            }
        }else{
            Pattern pattern = Pattern.compile(".*ts");
            Matcher ma = pattern.matcher(content);
            while(ma.find()){
                String s = ma.group();
                list.add(s);
            }
        }
        return list;
    }



    public static String getIndexFile(String urlpath){
        try{
            URL url = new URL(urlpath);
            //下在资源
            BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(),"UTF-8"));
            String content = "" ;
            String line;
            while ((line = in.readLine()) != null) {
                content += line + "\n";
            }
            in.close();
            return content;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
}
